# -*- coding: utf-8 -*-
"""
系统检测对话框模块
实现车辆系统检测功能的用户界面，包括连接检测、状态显示和结果管理

界面样式调整说明：
- GIF标签背景设置为透明，与主窗口背景完全一致，确保视觉统一性
- 按钮容器背景设置为透明，使用半透明边框适配不同主题
- 所有控件样式支持浅色和深色主题的自动适配
- 保持边距和间距符合UI设计规范，确保在不同分辨率下正确显示
"""

import time
from typing import Dict, Any, Optional

from PySide2.QtWidgets import (
    QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPushButton, 
    QFrame, QTextEdit, QSizePolicy, QSpacerItem,
    QMessageBox, QApplication
)
from PySide2.QtCore import Qt, QTimer, Signal, QThread, QMutex, QMutexLocker, QPropertyAnimation, QEasingCurve
from PySide2.QtGui import QPixmap, QMovie, QFont, QIcon

from gglobal import logger, config
from ..handlercore.language_manager import LanguageManager
from ..handlercore.theme_manager import ThemeManager
from ..handlercore.vehicle_connection_manager import VehicleConnectionManager
from ..handlercore.connection_manager import ConnectionStateManager
from ..handlercore.car_reconnect import CarReconnectManager
from ..handlercore import car_system_check


class SystemCheckThread(QThread):
    """
    系统检测线程类
    在后台执行车辆连接和系统检测，避免阻塞UI
    使用统一的连接管理器进行车辆连接
    """
    
    # 信号定义
    status_updated = Signal(str)  # 状态更新信号
    check_completed = Signal(dict)  # 检测完成信号，传递检测结果
    check_failed = Signal(str)  # 检测失败信号，传递错误信息
    connection_established = Signal(object)  # 连接建立信号，传递SSH客户端对象
    
    def __init__(self, ip_address: str, parent=None, vehicle_connection_manager=None):
        super(SystemCheckThread, self).__init__(parent)
        self.ip_address = ip_address
        self.parent_widget = parent
        self._stop_requested = False
        self._mutex = QMutex()
        
        # 使用传入的车辆连接管理器，如果没有传入则创建新的
        if vehicle_connection_manager:
            self.vehicle_connection_manager = vehicle_connection_manager
            # 从车辆连接管理器获取连接状态管理器
            self.connection_state_manager = vehicle_connection_manager._connection_manager
        else:
            # 兼容性处理：如果没有传入，则创建独立的连接管理器
            self.vehicle_connection_manager = VehicleConnectionManager(self)
            self.connection_state_manager = ConnectionStateManager(self)
        
        self.car_reconnect_manager = CarReconnectManager(LanguageManager(), self)
        
        # 登记连接持有者，避免在线程结束前被其他组件误断开
        try:
            if hasattr(self.vehicle_connection_manager, 'acquire'):
                self.vehicle_connection_manager.acquire(self)
        except Exception as e:
            logger.warning(f"[SystemCheckThread] 登记连接持有者失败: {e}")
        
        # 连接状态变化信号
        self.vehicle_connection_manager.connection_status_changed.connect(self._on_connection_status_changed)
        
        # 连接成功后的SSH客户端
        self.ssh_client = None
        
    def stop(self):
        """停止检测线程"""
        with QMutexLocker(self._mutex):
            self._stop_requested = True
            
        # 释放连接持有者：不强制断开，仅当无其他持有者时才会安全断开
        if self.vehicle_connection_manager:
            try:
                if hasattr(self.vehicle_connection_manager, 'release'):
                    self.vehicle_connection_manager.release(self)
                else:
                    # 兼容旧版本：仍执行原断开逻辑
                    self.vehicle_connection_manager.disconnect_from_vehicle()
            except Exception as e:
                logger.warning(f"[SystemCheckThread] 释放连接持有者失败，回退到断开逻辑: {e}")
                try:
                    self.vehicle_connection_manager.disconnect_from_vehicle()
                except Exception:
                    pass
        
    def is_stop_requested(self) -> bool:
        """检查是否请求停止"""
        with QMutexLocker(self._mutex):
            return self._stop_requested
    
    def run(self):
        """线程主执行方法"""
        try:
            logger.info(f"SystemCheckThread开始运行，目标IP: {self.ip_address}")
            # 使用QThread的正确方法获取线程ID
            try:
                thread_id = int(self.currentThread().currentThreadId()) if hasattr(self.currentThread(), 'currentThreadId') else 'unknown'
                logger.info(f"[SystemCheckThread] 线程ID: {thread_id}")
            except Exception as e:
                logger.debug(f"[SystemCheckThread] 无法获取线程ID: {e}")
            
            # 1. 尝试获取现有的有效SSH连接
            ssh_client = self._get_valid_ssh_client()
            if ssh_client:
                logger.info("[SystemCheckThread] 成功获取现有SSH连接，直接开始检测")
                self.ssh_client = ssh_client
                self.connection_established.emit(self.ssh_client)
                self._perform_system_check()
                return
            
            # 2. 等待连接建立
            logger.info("[SystemCheckThread] 等待连接建立...")
            if self._wait_for_connection():
                logger.info("[SystemCheckThread] 连接建立成功，开始系统检测")
                self.connection_established.emit(self.ssh_client)
                self._perform_system_check()
            else:
                error_msg = "连接等待超时，无法建立有效连接"
                logger.error(f"[SystemCheckThread] {error_msg}")
                self.check_failed.emit(error_msg)
            
        except Exception as e:
            error_msg = f"系统检测过程中发生异常: {str(e)}"
            logger.error(f"[SystemCheckThread] {error_msg}")
            self.check_failed.emit(error_msg)
    
    def _get_valid_ssh_client(self):
        """获取有效的ClientCarThread（上层封装）"""
        if not self.vehicle_connection_manager:
            logger.warning("[SystemCheckThread] 没有可用的车辆连接管理器")
            return None
        
        # 检查连接状态和IP匹配
        if not self.vehicle_connection_manager.is_connected():
            logger.debug("[SystemCheckThread] 车辆连接管理器显示未连接")
            return None
        
        current_ip = self.vehicle_connection_manager.get_connection_ip()
        if current_ip != self.ip_address:
            logger.debug(f"[SystemCheckThread] IP不匹配 - 目标: {self.ip_address}, 当前: {current_ip}")
            return None
        
        # 获取并验证SSH客户端（通过ClientCarThread封装）
        client_thread = self.vehicle_connection_manager.get_client_thread()
        if not client_thread or not hasattr(client_thread, 'ssh_client') or not client_thread.ssh_client:
            logger.debug("[SystemCheckThread] 无法获取SSH客户端")
            return None
        
        try:
            if client_thread.ssh_client.is_connection_alive():
                logger.info("[SystemCheckThread] SSH连接验证成功（返回ClientCarThread）")
                return client_thread
            else:
                logger.debug("[SystemCheckThread] SSH连接不可用")
                return None
        except Exception as e:
            logger.debug(f"[SystemCheckThread] SSH连接验证失败: {e}")
            return None
    
    def _wait_for_connection(self, max_wait_time=15, check_interval=0.5):
        """等待连接建立"""
        elapsed_time = 0
        
        while elapsed_time < max_wait_time and not self.is_stop_requested():
            self.msleep(int(check_interval * 1000))
            elapsed_time += check_interval
            
            # 检查是否有有效连接
            client_thread = self._get_valid_ssh_client()
            if client_thread:
                # 此处沿用成员名self.ssh_client用于信号兼容，但实际存储的是ClientCarThread
                self.ssh_client = client_thread
                # 同步连接状态到本地管理器
                if self.connection_state_manager:
                    self.connection_state_manager.set_connected(True, self.ip_address, "连接已建立")
                logger.info(f"[SystemCheckThread] 等待{elapsed_time:.1f}秒后检测到连接建立")
                return True
        
        logger.warning(f"[SystemCheckThread] 等待{elapsed_time:.1f}秒后仍未建立有效连接")
        return False
    
    def _on_connection_status_changed(self, is_connected: bool, message: str):
        """处理连接状态变化"""
        logger.info(f"[SystemCheckThread] 连接状态变化: connected={is_connected}, message={message}")
        
        # 同步状态到本地连接管理器
        if self.connection_state_manager:
            if is_connected:
                # 获取当前连接的IP地址
                current_ip = None
                if hasattr(self, 'vehicle_connection_manager') and self.vehicle_connection_manager:
                    current_ip = self.vehicle_connection_manager.get_connection_ip()
                
                if current_ip:
                    self.connection_state_manager.set_connected(True, current_ip, message)
                    logger.info(f"[SystemCheckThread] 同步连接状态: IP={current_ip}")
                else:
                    logger.warning("[SystemCheckThread] 无法获取连接IP地址")
            else:
                self.connection_state_manager.disconnect()
                logger.info("[SystemCheckThread] 同步断开状态")
    
    def sync_connection_state(self):
        """主动同步连接状态 - 确保状态一致性"""
        logger.debug("[SystemCheckThread] 开始同步连接状态")
        
        if hasattr(self, 'vehicle_connection_manager') and self.vehicle_connection_manager:
            parent_connection_manager = getattr(self.vehicle_connection_manager, '_connection_manager', None)
            if parent_connection_manager and parent_connection_manager != self.connection_state_manager:
                # 获取父级状态信息
                parent_status = parent_connection_manager.get_status_info()
                current_status = self.connection_state_manager.get_status_info()
                
                logger.info(f"[SystemCheckThread] 父级连接状态: {parent_status}")
                logger.info(f"[SystemCheckThread] 本地连接状态: {current_status}")
                
                # 如果状态不一致，以父级状态为准进行同步
                if (parent_status['is_connected'] != current_status['is_connected'] or 
                    parent_status['device_ip'] != current_status['device_ip']):
                    
                    logger.info(f"[SystemCheckThread] 检测到状态不一致，同步父级状态到本地: connected={parent_status['is_connected']}, ip={parent_status['device_ip']}")
                    
                    self.connection_state_manager.set_connected(
                        parent_status['is_connected'],
                        parent_status['device_ip'],
                        parent_status['message']
                    )
                    logger.info(f"[SystemCheckThread] 状态同步完成")
                    return True
                else:
                    logger.debug("[SystemCheckThread] 连接状态已同步，无需更新")
                    
                logger.debug(f"[SystemCheckThread] SystemCheckThread连接状态已同步: {parent_status}")
                return True
        else:
            logger.warning("[SystemCheckThread] 无法获取父级连接管理器，跳过状态同步")
            return False
    
    def _perform_system_check(self):
        """
        执行系统检测的具体逻辑
        """
        try:
            logger.info("[SystemCheckThread] 开始执行系统检测")
            
            # 检查是否被请求停止
            if self.is_stop_requested():
                logger.info("[SystemCheckThread] 检测被中止")
                return
            
            # 获取有效的ClientCarThread
            client_thread = self._get_valid_ssh_client()
            if not client_thread:
                error_msg = "无法获取有效的SSH连接"
                logger.error(f"[SystemCheckThread] {error_msg}")
                self.check_failed.emit(error_msg)
                return
            
            # 更新状态：开始检测（适配中英文）
            try:
                lm = LanguageManager()
                running_text = lm.get_constant("system_check_running", "正在执行系统检测...")
            except Exception:
                running_text = "正在执行系统检测..."
            self.status_updated.emit(running_text)
            
            # 执行检测
            logger.info("[SystemCheckThread] 调用car_system_check.perform_calibration_check_with_params")
            check_results = car_system_check.perform_calibration_check_with_params(client_thread)
            
            # 检查是否被请求停止
            if self.is_stop_requested():
                logger.info("[SystemCheckThread] 检测在执行过程中被中止")
                return
            
            # 更新状态
            try:
                lm2 = LanguageManager()
                saving_text = lm2.get_constant("system_check_saving_results", "正在保存检测结果...")
            except Exception:
                saving_text = "正在保存检测结果..."
            self.status_updated.emit(saving_text)
            
            # 保存检测结果
            self._save_check_results(check_results)
            
            # 完成检测
            try:
                lm3 = LanguageManager()
                completed_text = lm3.get_constant("system_check_completed", "检测完成")
            except Exception:
                completed_text = "检测完成"
            self.status_updated.emit(completed_text)
            
            logger.info("[SystemCheckThread] 系统检测成功完成")
            self.check_completed.emit(check_results)
            
        except Exception as e:
            error_msg = f"系统检测过程中发生错误: {str(e)}"
            logger.error(f"[SystemCheckThread] {error_msg}")
            self.check_failed.emit(error_msg)
    
    def _save_check_results(self, check_results: Dict[str, Any]):
        """保存检测结果到全局参数"""
        try:
            # 提取检测结果
            detection_results = check_results.get('detection_results', {})
            
            # 构建要保存的数据
            car_calibration_check = {
                'system_version': detection_results.get('system_version', ''),
                'kernel_version': detection_results.get('kernel_version', ''),
                'mooe_core_version': detection_results.get('mooe-core', ''),
                'rslidar_points': detection_results.get('rslidar_points', False),
                'scan_init_down': detection_results.get('scan_init_down', False),
                'scan_down_left': detection_results.get('scan_down_left', False),
                'scan_down_right': detection_results.get('scan_down_right', False),
                'livox_lidar': detection_results.get('livox_lidar', False),
                'camera1_depth_points': detection_results.get('camera1_depth_points', False),
                'camera2_depth_points': detection_results.get('camera2_depth_points', False),
                'camera1_color_image_raw': detection_results.get('camera1_color_image_raw', False),
                'camera2_color_image_raw': detection_results.get('camera2_color_image_raw', False),
                'last_check_time': time.time(),
                'check_status': 'completed' if check_results.get('overall_success', False) else 'failed'
            }
            
            # 保存到全局参数
            config.set_param('car_calibration_check', car_calibration_check)
            logger.info("检测结果已保存到全局参数 car_calibration_check")
            
        except Exception as e:
            logger.error(f"保存检测结果失败: {e}")


class SystemCheckDialog(QDialog):
    """
    系统检测对话框类
    提供车辆系统检测的用户界面，包括连接状态、检测进度和结果显示
    """
    
    # 信号定义
    check_completed = Signal(dict)  # 检测完成信号
    
    def __init__(self, ip_address: str, parent=None, vehicle_connection_manager=None):
        super(SystemCheckDialog, self).__init__(parent)
        self.ip_address = ip_address
        
        # 初始化组件
        self.language_manager = LanguageManager()
        self.theme_manager = ThemeManager()
        
        # 使用传入的车辆连接管理器，如果没有传入则创建新的
        if vehicle_connection_manager:
            self.vehicle_connection_manager = vehicle_connection_manager
            # 从车辆连接管理器获取连接状态管理器
            self.connection_state_manager = vehicle_connection_manager._connection_manager
        else:
            # 兼容性处理：如果没有传入，则创建独立的连接管理器
            self.connection_state_manager = ConnectionStateManager(self)
            self.vehicle_connection_manager = None
        
        self.car_reconnect_manager = CarReconnectManager(self.language_manager, self)
        
        # 检测线程
        self.check_thread = None
        
        # 状态管理
        self.is_checking = False
        self.check_results = {}
        
        # 线程安全锁
        self._mutex = QMutex()
        
        # 动画相关属性
        self.fade_animation = None
        self.checking_animation = None
        self.gif_animation = None
        
        # 连接重连管理器信号
        self.car_reconnect_manager.reconnection_completed.connect(self._on_reconnection_completed)
        
        # 初始化UI
        self.init_ui()
        self.setup_connections()
        self.register_language_widgets()
        
        # 设置窗口属性
        self.setModal(True)
        self.setFixedSize(500, 600)
        self.setWindowFlags(Qt.Dialog | Qt.WindowTitleHint | Qt.WindowCloseButtonHint)
        
        # 设置窗口标题（支持多语言）
        window_title = self.language_manager.get_text("system_check_dialog_title", "车辆系统检测")
        self.setWindowTitle(window_title)
        
        logger.info(f"系统检测对话框初始化完成，目标IP: {ip_address}")
    
    def init_ui(self):
        """初始化用户界面"""
        # 创建主布局
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(20, 20, 20, 20)
        main_layout.setSpacing(15)
        
        # 创建标题区域
        self.create_title_area(main_layout)
        
        # 创建显示区域
        self.create_display_area(main_layout)
        
        # 创建按钮区域
        self.create_button_area(main_layout)
        
        # 设置初始状态
        self.reset_ui_state()
    
    def create_title_area(self, layout):
        """创建标题区域 - 已移除系统检测标题标签"""
        # 标题区域已移除，保留方法以维持兼容性
        pass
    
    def create_display_area(self, layout):
        """创建显示区域 - 重构为两个独立界面"""
        # 创建主显示容器
        self.display_frame = QFrame()
        self.display_frame.setFrameStyle(QFrame.StyledPanel)
        self.display_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        
        # 创建堆叠布局来管理两个界面的切换
        from PySide2.QtWidgets import QStackedLayout
        self.stacked_layout = QStackedLayout(self.display_frame)
        
        # 创建检测过程界面
        self.create_checking_interface()
        
        # 创建检测结果界面
        self.create_result_interface()
        
        # 将检测过程界面设为默认显示
        self.stacked_layout.setCurrentIndex(0)
        
        layout.addWidget(self.display_frame)
    
    def create_checking_interface(self):
        """创建检测过程界面 - 简洁的GIF动画 + 文字提示"""
        checking_widget = QFrame()
        checking_layout = QVBoxLayout(checking_widget)
        checking_layout.setContentsMargins(40, 40, 40, 40)
        checking_layout.setSpacing(30)
        
        # 添加顶部弹性空间，使内容垂直居中
        checking_layout.addStretch(2)
        
        # GIF动画容器（居中布局）
        gif_container = QHBoxLayout()
        gif_container.addStretch()
        
        # GIF动画标签（增大尺寸以突出显示） - 样式已迁移到QSS文件
        self.loading_gif_label = QLabel()
        self.loading_gif_label.setObjectName("loading_gif_label")
        gif_width = 400  # 增大GIF尺寸
        gif_height = 400
        self.loading_gif_label.setFixedSize(gif_width, gif_height)
        self.loading_gif_label.setAlignment(Qt.AlignCenter)
        
        # 加载GIF动画
        try:
            self.loading_movie = QMovie(":/icon/loading.gif")
            if self.loading_movie.isValid():
                self.loading_movie.setScaledSize(self.loading_gif_label.size())
                self.loading_gif_label.setMovie(self.loading_movie)
                logger.debug(f"检测过程界面GIF动画加载成功，尺寸: {gif_width}x{gif_height}")
            else:
                logger.warning("GIF动画文件无效，使用备用显示")
                self.loading_gif_label.setText("检测中...")
        except Exception as e:
            logger.error(f"加载GIF动画失败: {e}")
            self.loading_gif_label.setText("检测中...")
            self.loading_movie = None
        
        gif_container.addWidget(self.loading_gif_label)
        gif_container.addStretch()
        checking_layout.addLayout(gif_container)
        
        # 检测状态文字提示 - 样式已迁移到QSS文件
        self.checking_status_label = QLabel("正在检测中...")
        self.checking_status_label.setObjectName("checking_status_label")
        self.checking_status_label.setWordWrap(True)
        self.checking_status_label.setAlignment(Qt.AlignCenter)
        checking_layout.addWidget(self.checking_status_label)
        
        # 详细状态信息（显示具体检测步骤，初始隐藏） - 样式已迁移到QSS文件
        self.detailed_status_label = QLabel("")
        self.detailed_status_label.setObjectName("detailed_status_label")
        self.detailed_status_label.setWordWrap(True)
        self.detailed_status_label.setAlignment(Qt.AlignCenter)
        self.detailed_status_label.setVisible(False)  # 初始隐藏，只在有具体步骤信息时显示
        checking_layout.addWidget(self.detailed_status_label)
        
        # 添加底部弹性空间
        checking_layout.addStretch(2)
        
        # 将检测过程界面添加到堆叠布局
        self.stacked_layout.addWidget(checking_widget)
        logger.debug("检测过程界面创建完成")
    
    def create_result_interface(self):
        """创建检测结果界面 - 完整结果显示 + 底部操作按钮"""
        result_widget = QFrame()
        result_layout = QVBoxLayout(result_widget)
        result_layout.setContentsMargins(20, 20, 20, 20)
        result_layout.setSpacing(15)
        
        # 结果状态标题 - 样式已迁移到QSS文件
        self.result_status_label = QLabel("检测完成！")
        self.result_status_label.setObjectName("result_status_label")
        self.result_status_label.setAlignment(Qt.AlignCenter)
        result_layout.addWidget(self.result_status_label)
        
        # 结果详细信息显示区域 - 样式已迁移到QSS文件
        self.result_text = QTextEdit()
        self.result_text.setObjectName("result_text")
        self.result_text.setReadOnly(True)
        self.result_text.setMinimumHeight(300)
        result_layout.addWidget(self.result_text)
        
        # 底部按钮区域 - 样式已迁移到QSS文件
        button_container = QFrame()
        button_container.setObjectName("button_container")
        button_layout = QHBoxLayout(button_container)
        button_layout.setContentsMargins(10, 10, 10, 10)
        button_layout.setSpacing(15)
        
        # 刷新按钮 - 样式已迁移到QSS文件
        self.refresh_button = QPushButton("重新检测")
        self.refresh_button.setObjectName("refresh_button")
        self.refresh_button.clicked.connect(self.refresh_check)
        button_layout.addWidget(self.refresh_button)
        
        # 添加弹性空间
        button_layout.addStretch()
        
        # 确认按钮 - 样式已迁移到QSS文件
        self.confirm_button = QPushButton("确认")
        self.confirm_button.setObjectName("confirm_button")
        self.confirm_button.clicked.connect(self.accept)
        button_layout.addWidget(self.confirm_button)
        
        result_layout.addWidget(button_container)
        
        # 将检测结果界面添加到堆叠布局
        self.stacked_layout.addWidget(result_widget)
        logger.debug("检测结果界面创建完成")
    
    def create_button_area(self, layout):
        """创建按钮区域 - 重构后按钮已集成到结果界面中，此方法保留用于兼容性"""
        # 注意：重构后按钮已经集成到检测结果界面中
        # 这里保留空实现以维持原有的方法调用结构
        logger.debug("按钮区域已集成到检测结果界面中，跳过独立按钮区域创建")
        pass
    
    def setup_connections(self):
        """设置信号连接 - 重构后连接新的按钮"""
        # 连接检测结果界面中的按钮信号
        self.refresh_button.clicked.connect(self.refresh_check)
        self.confirm_button.clicked.connect(self.accept)
        
        # 注册多语言支持
        self.language_manager.register_widget(self.refresh_button, "refresh_check_button")
        self.language_manager.register_widget(self.confirm_button, "confirm_button")
        
        # 注册检测过程界面的多语言支持
        self.language_manager.register_widget(self.checking_status_label, "checking_status_label")
        self.language_manager.register_widget(self.detailed_status_label, "detailed_status_label")
        
        # 注册检测结果界面的多语言支持
        self.language_manager.register_widget(self.result_status_label, "result_status_label")
        
        logger.debug("重构后的信号连接和多语言注册完成")
    
    def register_language_widgets(self):
        """注册多语言控件 - 重构后已集成到setup_connections中"""
        # 注意：多语言注册已经集成到setup_connections方法中
        # 这里保留空实现以维持原有的方法调用结构
        logger.debug("多语言注册已集成到setup_connections方法中，跳过重复注册")
        pass
    
    def refresh_check(self):
        """刷新检测 - 重构后的刷新逻辑"""
        logger.debug("用户点击刷新检测按钮")
        
        # 重置UI状态并切换到检测过程界面
        self.reset_ui_state()
        
        # 启动系统检测
        self.start_system_check()
        
        logger.debug("刷新检测完成，已重新启动检测流程")
    
    def reset_ui_state(self):
        """重置UI状态 - 重构后切换到检测过程界面"""
        try:
            # 重置检测状态标志 - 这是关键修复
            with QMutexLocker(self._mutex):
                self.is_checking = False
            logger.debug("已重置检测状态标志: is_checking = False")
            
            # 切换到检测过程界面（不使用动画，直接切换）
            self.switch_to_checking_interface(animated=False)
            
            # 重置检测过程界面状态（只显示主状态，不显示详细状态）
            self.update_checking_status("准备开始检测...")
            
            # 完全重置GIF动画状态
            if hasattr(self, 'loading_movie') and self.loading_movie:
                self.loading_movie.stop()
                # 重新设置GIF文件，使用Qt资源路径
                self.loading_movie.setFileName(":/icon/loading.gif")
                logger.debug("重新设置GIF文件: :/icon/loading.gif")
            
            # 重置GIF标签的透明度和可见性
            # 先停止任何正在进行的淡入/淡出动画
            if hasattr(self.loading_gif_label, '_fade_animation') and self.loading_gif_label._fade_animation:
                self.loading_gif_label._fade_animation.stop()
            
            # 重置透明度为1.0，但保持隐藏状态，等待后续的淡入动画
            self.loading_gif_label.setWindowOpacity(1.0)
            self.loading_gif_label.setVisible(False)
            logger.debug("GIF标签状态已重置：透明度=1.0，可见性=False")
            
            # 重置检测结果界面状态
            self.result_status_label.setText("检测完成！")
            self.result_status_label.setStyleSheet("""
                QLabel#result_status_label {
                    color: #2E7D32;
                    font-size: 18px;
                    font-weight: bold;
                    padding: 15px;
                    background-color: #E8F5E8;
                    border: 1px solid #C8E6C9;
                    border-radius: 8px;
                    margin-bottom: 10px;
                }
            """)
            self.result_text.clear()
            
            # 启用按钮
            self.refresh_button.setEnabled(True)
            self.confirm_button.setEnabled(True)
            
            logger.debug("UI状态重置完成，当前显示检测过程界面，GIF动画状态已完全重置")
            
        except Exception as e:
            logger.error(f"重置UI状态失败: {e}")
            # 如果重置失败，至少确保界面可用
            if hasattr(self, 'refresh_button'):
                self.refresh_button.setEnabled(True)
            if hasattr(self, 'confirm_button'):
                self.confirm_button.setEnabled(True)
    
    def start_system_check(self):
        """开始系统检测 - 增强状态同步"""
        with QMutexLocker(self._mutex):
            if self.is_checking:
                logger.warning("检测已在进行中，忽略重复请求")
                return
            
            self.is_checking = True
        
        # 在检测开始前重置车辆校准检测参数
        self._reset_calibration_params_before_check()
        
        # 更新UI状态
        self.update_ui_for_checking_state()
        
        # 启动Loading动画
        self.start_loading_animation()
        
        # 创建并启动检测线程，传入车辆连接管理器
        self.check_thread = SystemCheckThread(self.ip_address, self, self.vehicle_connection_manager)
        self.connect_thread_signals()
        self.check_thread.start()
        
        logger.info(f"开始系统检测，目标IP: {self.ip_address}")
    
    def update_ui_for_checking_state(self):
        """更新UI为检测状态 - 切换到检测过程界面"""
        # 切换到检测过程界面（带动画效果）
        self.switch_to_checking_interface(animated=True)
        
        # 确保GIF动画已正确初始化并重置状态
        if hasattr(self, 'loading_movie') and self.loading_movie:
            # 停止当前动画
            self.loading_movie.stop()
            
            # 重新设置GIF文件，使用Qt资源路径
            self.loading_movie.setFileName(":/icon/loading.gif")
            logger.debug("确保GIF文件已设置: :/icon/loading.gif")
            
            # 重新设置缩放尺寸
            self.loading_movie.setScaledSize(self.loading_gif_label.size())
            
            # 启动GIF动画
            self.loading_movie.start()
            logger.debug("GIF动画已重新启动")
        
        # 确保GIF标签状态正确
        if hasattr(self, 'loading_gif_label'):
            # 停止任何正在进行的淡入/淡出动画
            if hasattr(self.loading_gif_label, '_fade_animation') and self.loading_gif_label._fade_animation:
                self.loading_gif_label._fade_animation.stop()
            
            # 重置透明度并显示GIF动画（带淡入效果）
            self.loading_gif_label.setWindowOpacity(0.0)  # 从0开始淡入
            self._fade_in_widget(self.loading_gif_label)
            logger.debug("GIF标签淡入动画已启动")
        
        # 更新状态文本（只显示主状态，避免重复显示）
        connecting_text = self.language_manager.get_text("system_check_connecting", "正在连接车辆...")
        self.update_checking_status(connecting_text)
        
        # 禁用按钮
        self.refresh_button.setEnabled(False)
        self.confirm_button.setEnabled(False)
        
        logger.debug("UI已更新为检测状态：切换到检测过程界面并显示GIF动画")
    
    def start_loading_animation(self):
        """启动Loading动画"""
        if hasattr(self, 'loading_movie') and hasattr(self, 'loading_gif_label'):
            self.loading_gif_label.setVisible(True)
            self.loading_movie.start()
            logger.debug("Loading动画已启动")
    
    def stop_loading_animation(self):
        """停止Loading动画"""
        if hasattr(self, 'loading_movie') and hasattr(self, 'loading_gif_label'):
            self.loading_movie.stop()
            self.loading_gif_label.setVisible(False)
            logger.debug("Loading动画已停止")
    
    def connect_thread_signals(self):
        """连接线程信号"""
        if self.check_thread:
            self.check_thread.status_updated.connect(self.on_status_updated)
            self.check_thread.check_completed.connect(self.on_check_completed)
            self.check_thread.check_failed.connect(self.on_check_failed)
            self.check_thread.connection_established.connect(self.on_connection_established)
    
    def on_status_updated(self, status: str):
        """状态更新处理 - 更新检测过程界面的状态"""
        # 只在检测过程界面时更新状态
        if self.is_checking_interface_active():
            self.update_checking_status(status)
        logger.debug(f"检测状态更新: {status}")
    
    def on_connection_established(self, ssh_client):
        """连接建立处理"""
        logger.info("SSH连接已建立")
    
    def on_check_completed(self, results: Dict[str, Any]):
        """检测完成处理"""
        with QMutexLocker(self._mutex):
            self.is_checking = False
        
        self.check_results = results
        
        # 停止Loading动画
        self.stop_loading_animation()
        
        # 更新UI状态
        self.update_ui_for_completed_state(results)
        
        # 发送检测完成信号
        logger.info(f"[SystemCheckDialog] 准备发射check_completed信号，结果: {results}")
        self.check_completed.emit(results)
        logger.info("[SystemCheckDialog] check_completed信号已发射")
        
        logger.info("系统检测完成")
    
    def on_check_failed(self, error_msg: str):
        """检测失败处理 - 增强错误分类和处理机制"""
        with QMutexLocker(self._mutex):
            self.is_checking = False
        
        # 停止Loading动画
        self.stop_loading_animation()
        
        # 错误分类和处理
        error_type = self._classify_error(error_msg)
        
        if error_type == "connection_timeout":
            # 连接超时错误 - 不触发重连弹窗，直接显示错误
            logger.warning(f"连接超时错误: {error_msg}")
            self.update_ui_for_failed_state(error_msg)
            
        elif error_type == "connection_lost":
            # 连接丢失错误 - 提供重连选项
            logger.warning(f"连接丢失错误: {error_msg}")
            if self.check_thread and hasattr(self.check_thread, 'vehicle_connection_manager'):
                self.car_reconnect_manager.process_reconnection_request(
                    error_msg, 
                    None,  # file_manager (检测过程中不需要)
                    self.check_thread.vehicle_connection_manager
                )
            else:
                self.update_ui_for_failed_state(error_msg)
                
        elif error_type == "ssh_error":
            # SSH相关错误 - 提供重连选项
            logger.warning(f"SSH错误: {error_msg}")
            if self.check_thread and hasattr(self.check_thread, 'vehicle_connection_manager'):
                self.car_reconnect_manager.process_reconnection_request(
                    error_msg, 
                    None,
                    self.check_thread.vehicle_connection_manager
                )
            else:
                self.update_ui_for_failed_state(error_msg)
                
        elif error_type == "system_error":
            # 系统检测错误 - 直接显示，不触发重连
            logger.error(f"系统检测错误: {error_msg}")
            self.update_ui_for_failed_state(error_msg)
            
        else:
            # 其他未分类错误 - 直接显示
            logger.error(f"未分类错误: {error_msg}")
            self.update_ui_for_failed_state(error_msg)
        
        logger.error(f"系统检测失败: {error_msg}, 错误类型: {error_type}")
    
    def _classify_error(self, error_msg: str) -> str:
        """错误分类方法"""
        error_msg_lower = error_msg.lower()
        
        # 连接超时错误（不应触发重连弹窗）
        if any(keyword in error_msg_lower for keyword in ["连接超时", "connection timeout", "超时"]):
            return "connection_timeout"
        
        # 连接丢失错误（可以触发重连）
        if any(keyword in error_msg_lower for keyword in ["连接丢失", "connection lost", "连接断开", "disconnected"]):
            return "connection_lost"
        
        # SSH相关错误（可以触发重连）
        if any(keyword in error_msg_lower for keyword in ["ssh", "authentication", "认证失败", "无法获取ssh客户端"]):
            return "ssh_error"
        
        # 系统检测相关错误（不应触发重连）
        if any(keyword in error_msg_lower for keyword in ["系统检测", "检测失败", "rostopic", "传感器", "版本"]):
            return "system_error"
        
        # 网络相关错误（可以触发重连）
        if any(keyword in error_msg_lower for keyword in ["网络", "network", "无法建立车辆连接"]):
            return "connection_lost"
        
        return "unknown"
    
    def update_ui_for_completed_state(self, results: Dict[str, Any]):
        """更新UI为完成状态 - 切换到检测结果界面"""
        # 停止GIF动画
        if hasattr(self, 'loading_movie') and self.loading_movie:
            if self.loading_movie.state() == QMovie.Running:
                self.loading_movie.stop()
            self.loading_gif_label.setVisible(False)
            
            # 获取检测结果
            overall_success = results.get('overall_success', False)
            detection_results = results.get('detection_results', {})
            
            # 重置检测结果界面状态
            self.result_status_label.setText("检测完成！")
            # 动态设置状态属性用于QSS样式选择 - 样式已迁移到QSS文件
            if overall_success:
                self.result_status_label.setProperty("status", "success")
            else:
                self.result_status_label.setProperty("status", "error")
            self.result_status_label.style().unpolish(self.result_status_label)
            self.result_status_label.style().polish(self.result_status_label)
            
            self.result_text.clear()
            
            # 显示详细结果
            self.show_detailed_results(detection_results)
            logger.info(f"系统检测结果: {detection_results}")
            
            # 切换到检测结果界面（带动画效果）
            self.switch_to_result_interface(animated=True)
            
            # 恢复按钮状态
            self.refresh_button.setEnabled(True)
            self.confirm_button.setEnabled(True)
            
            logger.debug("UI已更新为完成状态：切换到检测结果界面")
    
    def update_ui_for_failed_state(self, error_msg: str):
        """更新UI为失败状态 - 切换到检测结果界面显示错误"""
        # 停止GIF动画
        if hasattr(self, 'loading_movie') and self.loading_movie:
            self.loading_movie.stop()
        self.loading_gif_label.setVisible(False)
        
        # 更新结果状态标签为失败状态
        self.result_status_label.setText("检测失败！")
        # 动态设置状态属性用于QSS样式选择
        self.result_status_label.setProperty("status", "error")
        self.result_status_label.style().unpolish(self.result_status_label)
        self.result_status_label.style().polish(self.result_status_label)
        
        # 显示错误信息
        self.result_text.setPlainText(f"错误详情:\n{error_msg}")
        
        # 切换到检测结果界面（带动画效果）
        self.switch_to_result_interface(animated=True)
        
        # 恢复按钮状态
        self.refresh_button.setEnabled(True)
        self.confirm_button.setEnabled(True)
        
        logger.debug("UI已更新为失败状态：切换到检测结果界面显示错误信息")
    
    def show_detailed_results(self, detection_results: Dict[str, Any]):
        """显示详细检测结果 - 格式化显示在结果界面"""
        # 使用 LanguageManager 适配中英文（统一从 constants 读取，避免类别不匹配导致中文回退）
        lm = self.language_manager if hasattr(self, "language_manager") else LanguageManager()
        result_text = ""

        # 系统信息（标题与标签本地化，使用常量类别）
        sys_header = lm.get_constant("system_info_header") or "=== 系统信息 ==="
        unknown_text = lm.get_constant("unknown_text") or "未知"
        sys_ver_label = lm.get_constant("system_version_label") or "系统版本"
        kernel_ver_label = lm.get_constant("kernel_version_label") or "内核版本"
        mooe_core_label = lm.get_constant("mooe_core_version_label") or "mooe-core版本"

        result_text += f"{sys_header}\n"
        result_text += f"{sys_ver_label}: {detection_results.get('system_version', unknown_text)}\n"
        result_text += f"{kernel_ver_label}: {detection_results.get('kernel_version', unknown_text)}\n"
        result_text += f"{mooe_core_label}: {detection_results.get('mooe-core', unknown_text)}\n\n"

        # 传感器状态（标题与传感器名称本地化，传感器名统一从常量类别读取）
        sensor_header = lm.get_constant("sensor_status_header") or "=== 传感器状态 ==="
        result_text += f"{sensor_header}\n"

        sensors = [
            ("rslidar_points", lm.get_constant("sensor_display_rslidar_points") or "上激光雷达"),
            ("scan_init_down", lm.get_constant("sensor_display_scan_init_down") or "下激光雷达"),
            ("livox_lidar", lm.get_constant("sensor_display_livox_lidar") or "Mid360激光"),
            ("camera1_depth_points", lm.get_constant("sensor_display_camera1_depth_points") or lm.get_text("data_detection_left_fork_camera", "左叉臂相机")),
            ("camera2_depth_points", lm.get_constant("sensor_display_camera2_depth_points") or lm.get_text("data_detection_right_fork_camera", "右叉臂相机")),
            ("camera1_color_image_raw", lm.get_constant("sensor_display_camera1_color_image_raw") or "左相机彩色图像"),
            ("camera2_color_image_raw", lm.get_constant("sensor_display_camera2_color_image_raw") or "右相机彩色图像"),
        ]

        ok_text = lm.get_constant("sensor_status_ok") or "✓ 正常"
        err_text = lm.get_constant("sensor_status_error") or "✗ 异常"
        for sensor_key, sensor_name in sensors:
            if sensor_key == "scan_init_down":
                status = bool(detection_results.get("scan_init_down", False)) or (
                    bool(detection_results.get("scan_down_left", False)) and bool(detection_results.get("scan_down_right", False))
                )
            else:
                status = bool(detection_results.get(sensor_key, False))
            status_text = ok_text if status else err_text
            result_text += f"{sensor_name}: {status_text}\n"

        # 检测时间信息（标签与单位本地化，使用常量类别）
        if "detection_time" in detection_results:
            time_label = lm.get_constant("detection_time_label") or "检测耗时"
            seconds_unit = lm.get_constant("seconds_unit") or "秒"
            result_text += f"\n{time_label}: {detection_results['detection_time']:.2f}{seconds_unit}\n"

        # 更新到结果文本区域
        self.result_text.setPlainText(result_text)
        
        # 确保界面刷新
        QApplication.processEvents()
    
    def _on_reconnection_completed(self, success: bool, message: str):
        """处理重连完成事件 - 重构后适配新界面"""
        logger.info(f"重连完成: success={success}, message={message}")
        
        if success:
            # 重连成功，可以选择自动重新开始检测
            reply = QMessageBox.question(
                self, 
                self.language_manager.get_text("reconnection_success_title", "重连成功"),
                f"{self.language_manager.get_text('auto_restart_check', '重连成功！是否自动重新开始检测？')}\n\n{message}",
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.Yes
            )
            
            if reply == QMessageBox.Yes:
                # 自动重新开始检测
                self.start_system_check()
        else:
            # 重连失败，显示失败状态
            self.update_ui_for_failed_state(f"重连失败: {message}")
    
    def switch_to_checking_interface(self, animated=True):
        """切换到检测过程界面 - 支持动画效果"""
        if animated:
            self._animate_interface_switch(0)
        else:
            self.stacked_layout.setCurrentIndex(0)
        logger.debug("已切换到检测过程界面")
    
    def switch_to_result_interface(self, animated=True):
        """切换到检测结果界面 - 支持动画效果"""
        if animated:
            self._animate_interface_switch(1)
        else:
            self.stacked_layout.setCurrentIndex(1)
        logger.debug("已切换到检测结果界面")
    
    def _animate_interface_switch(self, target_index):
        """界面切换动画 - 实现平滑过渡效果"""
        try:
            from PySide2.QtCore import QPropertyAnimation, QEasingCurve
            from PySide2.QtWidgets import QGraphicsOpacityEffect
            
            current_index = self.stacked_layout.currentIndex()
            if current_index == target_index:
                return  # 已经是目标界面，无需切换
            
            # 获取当前和目标界面
            current_widget = self.stacked_layout.widget(current_index)
            target_widget = self.stacked_layout.widget(target_index)
            
            if not current_widget or not target_widget:
                # 如果获取不到界面，直接切换
                self.stacked_layout.setCurrentIndex(target_index)
                return
            
            # 创建透明度效果
            current_opacity_effect = QGraphicsOpacityEffect()
            target_opacity_effect = QGraphicsOpacityEffect()
            
            current_widget.setGraphicsEffect(current_opacity_effect)
            target_widget.setGraphicsEffect(target_opacity_effect)
            
            # 设置初始状态
            current_opacity_effect.setOpacity(1.0)
            target_opacity_effect.setOpacity(0.0)
            
            # 切换到目标界面（此时透明度为0，用户看不到）
            self.stacked_layout.setCurrentIndex(target_index)
            
            # 创建淡出动画（当前界面）
            self.fade_out_animation = QPropertyAnimation(current_opacity_effect, b"opacity")
            self.fade_out_animation.setDuration(200)  # 200ms动画时长
            self.fade_out_animation.setStartValue(1.0)
            self.fade_out_animation.setEndValue(0.0)
            self.fade_out_animation.setEasingCurve(QEasingCurve.OutCubic)
            
            # 创建淡入动画（目标界面）
            self.fade_in_animation = QPropertyAnimation(target_opacity_effect, b"opacity")
            self.fade_in_animation.setDuration(250)  # 稍长的淡入时间
            self.fade_in_animation.setStartValue(0.0)
            self.fade_in_animation.setEndValue(1.0)
            self.fade_in_animation.setEasingCurve(QEasingCurve.OutCubic)
            
            # 动画完成后清理效果
            def cleanup_animation():
                try:
                    current_widget.setGraphicsEffect(None)
                    target_widget.setGraphicsEffect(None)
                    logger.debug(f"界面切换动画完成，当前界面索引: {target_index}")
                except Exception as e:
                    logger.warning(f"清理动画效果时出错: {e}")
            
            self.fade_in_animation.finished.connect(cleanup_animation)
            
            # 启动动画（先淡入目标界面）
            self.fade_in_animation.start()
            
            logger.debug(f"启动界面切换动画: {current_index} -> {target_index}")
            
        except Exception as e:
            logger.warning(f"界面切换动画失败，使用直接切换: {e}")
            # 动画失败时直接切换
            self.stacked_layout.setCurrentIndex(target_index)
    
    def update_checking_status(self, main_status: str, detail_status: str = None):
        """更新检测过程界面的状态信息 - 优化显示逻辑"""
        self.checking_status_label.setText(main_status)
        
        # 只有在提供详细状态且与主状态不同时才显示详细状态标签
        if detail_status and detail_status != main_status and detail_status.strip():
            self.detailed_status_label.setText(detail_status)
            self.detailed_status_label.setVisible(True)
        else:
            self.detailed_status_label.setVisible(False)
            
        logger.debug(f"检测状态更新: {main_status}" + (f" | 详细: {detail_status}" if detail_status and detail_status != main_status else ""))
    
    def get_current_interface_index(self):
        """获取当前显示的界面索引 - 新增方法用于状态查询"""
        return self.stacked_layout.currentIndex()
    
    def is_checking_interface_active(self):
        """判断是否为检测过程界面 - 新增方法用于状态判断"""
        return self.get_current_interface_index() == 0
    
    def is_result_interface_active(self):
        """判断是否为检测结果界面 - 新增方法用于状态判断"""
        return self.get_current_interface_index() == 1
    
    def closeEvent(self, event):
        """窗口关闭事件"""
        # 在关闭前重置车辆校准检测参数
        self._reset_calibration_params_on_disconnect()
        
        # 如果正在检测，停止检测线程
        if self.check_thread and self.check_thread.isRunning():
            self.check_thread.stop()
            self.check_thread.wait(3000)  # 等待最多3秒
            
        logger.info("系统检测对话框关闭")
        super().closeEvent(event)
    
    def sync_connection_state(self):
        """同步连接状态 - 保持与父级连接管理器的状态一致"""
        logger.debug("[SystemCheckDialog] 开始同步连接状态")
        
        if hasattr(self, 'vehicle_connection_manager') and self.vehicle_connection_manager:
            parent_connection_manager = getattr(self.vehicle_connection_manager, '_connection_manager', None)
            if parent_connection_manager and parent_connection_manager != self.connection_state_manager:
                # 获取父级状态信息
                parent_status = parent_connection_manager.get_status_info()
                current_status = self.connection_state_manager.get_status_info()
                
                logger.info(f"[SystemCheckDialog] 父级连接状态: {parent_status}")
                logger.info(f"[SystemCheckDialog] 本地连接状态: {current_status}")
                
                # 如果状态不一致，以父级状态为准进行同步
                if (parent_status['is_connected'] != current_status['is_connected'] or 
                    parent_status['device_ip'] != current_status['device_ip']):
                    
                    logger.info(f"[SystemCheckDialog] 检测到状态不一致，同步父级状态到本地: connected={parent_status['is_connected']}, ip={parent_status['device_ip']}")
                    
                    self.connection_state_manager.set_connected(
                        parent_status['is_connected'],
                        parent_status['device_ip'],
                        parent_status['message']
                    )
                    logger.info(f"[SystemCheckDialog] 状态同步完成")
                    return True
                else:
                    logger.debug("[SystemCheckDialog] 连接状态已同步，无需更新")
                    
                logger.debug(f"[SystemCheckDialog] SystemCheckThread连接状态已同步: {parent_status}")
                return True
        else:
            logger.warning("[SystemCheckDialog] 无法获取父级连接管理器，跳过状态同步")
            return False
    
    def _fade_in_widget(self, widget):
        """控件淡入动画"""
        if not widget:
            return
            
        # 停止之前的动画
        if hasattr(widget, '_fade_animation') and widget._fade_animation:
            widget._fade_animation.stop()
        
        # 设置初始状态
        widget.setVisible(True)
        
        # 创建透明度动画
        animation = QPropertyAnimation(widget, b"windowOpacity")
        animation.setDuration(300)  # 300ms动画时长
        animation.setStartValue(0.0)
        animation.setEndValue(1.0)
        animation.setEasingCurve(QEasingCurve.OutCubic)
        
        # 保存动画引用
        widget._fade_animation = animation
        
        # 启动动画
        animation.start()
        
        logger.debug(f"启动淡入动画: {widget.__class__.__name__}")
    
    def _fade_out_widget(self, widget):
        """控件淡出动画"""
        if not widget or not widget.isVisible():
            return
            
        # 停止之前的动画
        if hasattr(widget, '_fade_animation') and widget._fade_animation:
            widget._fade_animation.stop()
        
        # 创建透明度动画
        animation = QPropertyAnimation(widget, b"windowOpacity")
        animation.setDuration(300)  # 300ms动画时长
        animation.setStartValue(1.0)
        animation.setEndValue(0.0)
        animation.setEasingCurve(QEasingCurve.InCubic)
        
        # 动画完成后隐藏控件
        animation.finished.connect(lambda: widget.setVisible(False))
        
        # 保存动画引用
        widget._fade_animation = animation
        
        # 启动动画
        animation.start()
        
        logger.debug(f"启动淡出动画: {widget.__class__.__name__}")
    
    def get_check_results(self) -> Dict[str, Any]:
        """获取检测结果"""
        return self.check_results.copy()
    
    def _reset_calibration_params_before_check(self):
        """在检测开始前重置车辆校准检测参数"""
        try:
            logger.info("检测开始前重置车辆校准检测参数...")
            reset_result = car_system_check.reset_calibration_check_params()
            
            if reset_result["success"]:
                logger.info("检测开始前参数重置成功")
            else:
                logger.error(f"检测开始前参数重置失败: {reset_result.get('error', '未知错误')}")
                
        except Exception as e:
            logger.error(f"检测开始前重置参数时发生异常: {str(e)}")
    
    def _reset_calibration_params_on_disconnect(self):
        """在断开连接时重置车辆校准检测参数"""
        try:
            logger.info("断开连接时重置车辆校准检测参数...")
            reset_result = car_system_check.reset_calibration_check_params()
            
            if reset_result["success"]:
                logger.info("断开连接时参数重置成功")
            else:
                logger.error(f"断开连接时参数重置失败: {reset_result.get('error', '未知错误')}")
                
        except Exception as e:
            logger.error(f"断开连接时重置参数时发生异常: {str(e)}")